﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using Microsoft.ResourceManagement.Utilities;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
using Microsoft.ResourceManagement.Workflow.Activities;

namespace Ensynch.ILM2.Workflow.Activities
{
    public partial class DiagnosticActivity : SequenceActivity
    {
        public DiagnosticActivity()
        {
            InitializeComponent();
        }

        #region Activity Properties

        public RequestType currentRequest;

        public static DependencyProperty TheActivityNameProperty =
            DependencyProperty.Register("TheActivityName", typeof(string), typeof(DiagnosticActivity));

        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("Properties")]
        public string TheActivityName
        {
            get { return (string)this.GetValue(DiagnosticActivity.TheActivityNameProperty); }
            set
            {
                this.SetValue(DiagnosticActivity.TheActivityNameProperty, value);
            }
        }

        public static DependencyProperty LogFolderProperty =
                    DependencyProperty.Register("LogFolder", typeof(string), typeof(DiagnosticActivity));

        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("Properties")]
        public string LogFolder
        {
            get { return (string)this.GetValue(DiagnosticActivity.LogFolderProperty); }
            set
            {
                this.SetValue(DiagnosticActivity.LogFolderProperty, value);
            }
        }

        public static DependencyProperty LogFileProperty =
                    DependencyProperty.Register("LogFile", typeof(string), typeof(DiagnosticActivity));

        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("Properties")]
        public string LogFile
        {
            get { return (string)this.GetValue(DiagnosticActivity.LogFileProperty); }
            set
            {
                this.SetValue(DiagnosticActivity.LogFileProperty, value);
            }
        }

        #endregion

        #region Event Processing

        protected override void OnSequenceComplete(ActivityExecutionContext executionContext)
        {
            try
            {
                SequentialWorkflow containingWorkflow = null;
                if (!SequentialWorkflow.TryGetContainingWorkflow(this, out containingWorkflow))
                {
                    throw new InvalidOperationException("Unable to get Containing Workflow");
                }
                //
                // Output the Request type and object type
                //
                this.SimpleLogFunction("Request Object Type    = \"" + this.GetObjectType() + "\"", "", EventLogEntryType.Information, 10002, 100);
                this.SimpleLogFunction("Request Operation Type = \"" + this.GetOperation() + "\"", "", EventLogEntryType.Information, 10002, 100);
                //
                // UpdateRequestParameter derives from CreateRequestParameter.  Since we only need PropertyName / value pairs,
                // simplify the code to work on CreateRequestParameter only.
                //
                ReadOnlyCollection<CreateRequestParameter> requestParameters = this.currentRequest.ParseParameters<CreateRequestParameter>();
                //
                // Traverse CreateRequestParameters in and print out each attribute in the request
                // 
                this.SimpleLogFunction("Cycle Through the Request Parameters", "", EventLogEntryType.Information, 10002, 100);

                foreach (CreateRequestParameter requestParameter in requestParameters)
                {
                    this.SimpleLogFunction("RequestParameter (\"" + requestParameter.PropertyName + "\")",
                                           " = \"" + requestParameter.Value.ToString() + "\"", EventLogEntryType.Information, 10002, 100);
                }

                this.SimpleLogFunction("Cycle Through the Workflow Dictionary", "", EventLogEntryType.Information, 10002, 100);

                foreach (KeyValuePair<string, object> dItem in containingWorkflow.WorkflowDictionary)
                {
                    this.SimpleLogFunction("Dictionary Entry (\"" + dItem.Key + "\")",
                                           " = \"" + dItem.Value.ToString() + "\"", EventLogEntryType.Information, 10002, 100);
                }
            }
            catch (Exception ex)
            {
                this.SimpleLogFunction("Diagnostic Log Entry Request Exception", " = '" + ex.Message + "'", EventLogEntryType.Error, 10005, 100);
            }
            finally
            {
                base.OnSequenceComplete(executionContext);
            }
        }
        protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
        {
            SimpleLogFunction("HandleFault", exception.Message, EventLogEntryType.Error, 1000, 100);

            return ActivityExecutionStatus.Closed;
        }

        #endregion

        #region Utility Functions

        private void SimpleLogFunction(string functionName, string Message, EventLogEntryType type, int eventID, short category)
        {
            string delim = "";

            using (StreamWriter mylog = new StreamWriter(Path.Combine(this.LogFolder, this.LogFile), true))
            {
                mylog.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + ": " +
                                this.TheActivityName + ": " +
                                functionName + ", " + Message);
                mylog.Close();
            }
        }

        private string GetOperation()
        {
            switch (this.currentRequest.Operation)
            {
                case OperationType.Create:
                    return "Create";
                case OperationType.Delete:
                    return "Delete";
                case OperationType.Enumerate:
                    return "Enumerate";
                case OperationType.Get:
                    return "Get";
                case OperationType.Pull:
                    return "Pull";
                case OperationType.Put:
                    return "Put";
                case OperationType.SystemEvent:
                    return "System Event";
                default:
                    return "Unknown Operation";
            }
        }

        private string GetObjectType()
        {
            return currentRequest.TargetObjectType;
        }

        #endregion


    }
}
